Skip to content

Fix release governance and offline readiness blockers#655

Merged
BigSimmo merged 13 commits into
mainfrom
codex/release-blocker-remediation
Jul 14, 2026
Merged

Fix release governance and offline readiness blockers#655
BigSimmo merged 13 commits into
mainfrom
codex/release-blocker-remediation

Conversation

@BigSimmo

@BigSimmo BigSimmo commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Adds a provider-free, idempotent registry governance reconciliation that can repair deterministic registry metadata and labels without touching chunks, embeddings, or OpenAI.
  • Adds explicit offline quality/release gates and production-readiness behavior for deployments configured with RAG_PROVIDER_MODE=offline.
  • Adds isolated staging tenancy automation/evidence, owner-scoped answer history, route latency budgets, and document-viewer/UI resilience changes.

Verification

  • npm run verify:pr-local — aggregate attempt reached format/lint/typecheck, then the Vitest worker exited without an assertion summary. Its constituent gates passed independently as listed below.
  • npm run verify:cheap — 254 files passed, 1 skipped; 2,325 tests passed, 1 skipped.
  • Isolated full Vitest run after the health fix — 254 files passed, 1 skipped; 2,328 tests passed, 1 skipped.
  • Focused remediation suites — 11 files / 207 tests passed; health/config follow-up 3 files / 15 tests passed.
  • npm run verify:ui — Chromium and Chromium mockups, 163/163 passed.
  • Targeted changed-surface Firefox/WebKit — 36/36 passed.
  • Offline production build — 653 pages generated; client bundle secret scan passed.
  • npm run eval:rag:offline — 36 fixtures; 21 files / 280 tests passed.
  • npm run check:github-actions, npm run check:ci-scope, format, typecheck, and diff checks passed.
  • Full Firefox/WebKit aggregate — skipped after the host killed the process under memory pressure after 81 Firefox tests passed and no assertion failure.
  • Fresh local Supabase replay — skipped after Docker could not bind the repo default port because it is inside a Windows reserved port range. Hosted migration verification is authoritative.
  • npm run eval:quality:release and npm run verify:release — intentionally deferred; they require OpenAI credits and remain unchanged.
  • npm run check:production-readiness against live production — local offline behavior passed the missing-OpenAI condition and failed only on intentionally absent Supabase production variables. Live identity/readiness is a pre-merge gate.

Clinical Governance Preflight

  • Source-backed claims still require linked source verification before clinical use.
  • No patient-identifiable document workflow was introduced or expanded.
  • Production target remains Clinical KB Database (sjrfecxgysukkwxsowpy); the reconciliation has an expected-project-ref guard.
  • Service-role keys and private document access remain server-only.
  • Staging tenancy data is synthetic and isolated from production.
  • Source metadata, review status, and unknown-source behavior remain conservative.
  • The change does not broaden clinical decision-support claims; the existing SaMD note remains applicable.

Release notes and remaining gates

  • No OpenAI request is permitted in this release path. The new offline report rejects provider/model/request/token/cost/generation evidence.
  • Production mutation is limited to registry document governance metadata and generated labels. It reports and enforces zero chunk rows and zero OpenAI calls.
  • Before ready/merge: provision isolated staging, pass cross-tenant cleanup/evidence, run the production registry dry-run/write/idempotency proof, require zero governance gaps, and require hosted checks/review threads to be green.

Summary by CodeRabbit

  • New Features
    • Added deterministic clinical review queue generation from evaluation results.
    • Added registry governance reconciliation and offline release verification.
    • Added staging tenancy isolation harness plus release-evidence process and workflow.
  • Improvements
    • Added route-time budgeting diagnostics and deadline enforcement for answer routing.
    • Improved answer-thread persistence isolation and document viewer URL/page sync.
  • Bug Fixes
    • Offline health checks now correctly skip OpenAI config validation.
    • UI scrolling/interaction reliability improved across browsers, with safer extractive fallbacks.
  • Documentation
    • Updated staging setup and process hardening with cross-tenant evidence requirements.

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The head commit changed during the review from dedb38a to 1ece1b8.

📝 Walkthrough

Walkthrough

This PR adds staging cross-tenant regression testing, offline release verification, registry governance reconciliation, clinical review queue generation, RAG route deadlines and evaluation diagnostics, plus UI persistence, navigation, loading, and browser-test updates.

Changes

Staging isolation and offline release

Layer / File(s) Summary
Staging workflow and evidence
.env.example, .github/workflows/*, docs/staging-*, docs/process-hardening.md, docs/branch-review-ledger.md, package.json
Adds scheduled/manual staging tenancy verification, environment placeholders, evidence retention, offline staging guidance, release scripts, and review records.
Cross-tenant harness
scripts/test-cross-tenant-staging.ts, tests/cross-tenant-staging-config.test.ts
Validates staging configuration, exercises tenant boundaries with synthetic fixtures, cleans up resources, writes evidence, and tests fail-fast safety rules.
Offline release profile
scripts/*offline*, scripts/eval-quality.ts, scripts/production-readiness.ts, src/instrumentation.ts, src/lib/health-response.ts, tests/*offline*, tests/health-route.test.ts, tests/instrumentation.test.ts
Adds explicit offline provider handling and removes OpenAI credential requirements from offline verification paths.

Governance, evaluation, and RAG controls

Layer / File(s) Summary
Review queue and label contracts
src/lib/clinical-review-queue.ts, scripts/build-clinical-review-queue.ts, scripts/check-document-label-coverage.ts, scripts/classify-documents.ts, tests/*queue*, tests/*label*
Builds deterministic clinical review queues, validates registry metadata and labels, and excludes registry projections from generic classification.
Registry governance
src/lib/registry-corpus.ts, scripts/reconcile-registry-governance.ts, tests/registry-*, tests/retrieval-owner-filter-guard.test.ts
Adds registry intent and validation metadata, generated-label reconciliation, ownership checks, project-ref validation, and dry-run/write governance planning.
RAG deadlines and evaluation
src/lib/rag-route-budget.ts, src/lib/rag.ts, src/lib/types.ts, scripts/eval-quality.ts, tests/rag-*, tests/eval-quality.test.ts
Introduces route-specific deadlines and timing diagnostics, applies deadline races to RAG operations, and records provider and route-ceiling evaluation failures.

UI loading and interaction reliability

Layer / File(s) Summary
Answer and document state
src/components/ClinicalDashboard.tsx, src/lib/answer-thread-storage.ts, src/app/page.tsx
Preloads the answer surface, scopes persisted-thread cleanup by owner, parses recent queries through cancellable microtasks, and waits for server connection during initial rendering.
Viewer navigation and review sheets
src/components/DocumentViewer.tsx, src/components/document-viewer/*, src/components/clinical-dashboard/*
Resets scroll state when pinned content changes, synchronizes PDF page URLs, consolidates review-sheet state, and replaces dashboard dynamic loading with a static import.
Browser smoke coverage
tests/ui-*.spec.ts, tests/playwright-scroll.ts
Adds mocked registry/search/clipboard data and synchronizes fullscreen, keyboard, focus, scroll, and React event-handler interactions.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.44% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main changes: release governance, offline readiness, and blockers being fixed.
Description check ✅ Passed The description covers Summary, Verification, and the governance preflight, but it does not include the template’s Notes section.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/release-blocker-remediation

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands.

@supabase

supabase Bot commented Jul 14, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@BigSimmo
BigSimmo marked this pull request as ready for review July 14, 2026 11:10

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ca2f9f372

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/production-readiness.ts
@BigSimmo

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts on this branch.

@BigSimmo

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts on this branch.

Resolved merge conflict in docs/branch-review-ledger.md by keeping all entries from both branches in chronological order.
auto-merge was automatically disabled July 14, 2026 11:42

Head branch was pushed to by a user without write access

Copilot AI commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts on this branch.

Merge conflicts resolved in commit 409d6e8. The conflict in docs/branch-review-ledger.md has been resolved by keeping all branch review entries from both branches in chronological order.

@BigSimmo
BigSimmo enabled auto-merge (squash) July 14, 2026 11:45

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/components/clinical-dashboard/global-search-shell.tsx (1)

2-3: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Keep ClinicalDashboard code-split

Static importing ClinicalDashboard pulls the 4k-line dashboard module into every GlobalSearchShell route, even when the standalone shell branch renders. Restore the lazy import if you want to preserve the old bundle split.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/clinical-dashboard/global-search-shell.tsx` around lines 2 -
3, Update GlobalSearchShell’s ClinicalDashboard dependency to use the existing
lazy/dynamic import pattern instead of a static import, preserving
code-splitting so standalone shell routes do not load the dashboard module. Keep
the ClinicalDashboard rendering behavior unchanged when that branch is selected.

Source: Path instructions

tests/ui-smoke.spec.ts (1)

56-69: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test helper relies on undocumented React DOM internals.

waitForReactEventHandler detects handler attachment via __reactProps$*, an internal fiber-props property name that React does not guarantee across versions. This is a P2/test-quality concern (not a functional bug today) surfaced once here rather than at each of its five call sites (Lines 2860, 2905-2906, 2936, 2967, 3008), per the file's JS/TS review policy of limiting inline findings and consolidating P2 context into one comment.

Consider a stable alternative that doesn't depend on React internals, e.g. having the component set a data-scroll-ready attribute (or similar) once its scroll handler is mounted, and polling that instead.

As per coding guidelines, **/*.{js,jsx,ts,tsx,mjs,cjs} review policy states: "Automatic reviews may emit at most three inline findings, and inline comments are limited to P0/P1 issues; P2 context belongs in one summary," which is why this single note covers all waitForReactEventHandler usages in this file rather than repeating per call site.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/ui-smoke.spec.ts` around lines 56 - 69, Replace the undocumented
React-props inspection in waitForReactEventHandler with a stable readiness
signal exposed by the relevant component, such as a data-scroll-ready attribute
set when its scroll handler is mounted. Update the helper to poll that attribute
through the Locator API, preserving its timeout and success behavior, and ensure
all existing call sites continue using the helper unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/test-cross-tenant-staging.ts`:
- Around line 471-486: Ensure the successful reindex path in the staging harness
does not proceed directly to cleanup after the 201 response: either poll the
queued reindex job until it reaches a terminal state, or skip executing the real
reindex while retaining the status-code assertion if only response validation is
needed. Update the flow around the second requestJson call and the “reindex”
checkpoint.

In `@src/components/ClinicalDashboard.tsx`:
- Line 756: Move the activeAnswerThreadOwnerIdRef.current assignment out of the
ClinicalDashboard render path and into the existing effect that responds to
answerThreadOwnerId changes, alongside previousAnswerThreadOwnerIdRef updates.
Preserve the current assignment timing and owner-gating behavior while ensuring
both refs are updated only after the render commits.

In `@src/components/DocumentViewer.tsx`:
- Around line 2581-2583: Update the onPageChange handler in DocumentViewer to
navigate through the existing Next.js router/state mechanism instead of calling
window.history.pushState. Ensure page changes update selectedPage and all
dependent UI, including the subtitle and useHideOnScroll, while preserving the
documentPageHref destination.

---

Nitpick comments:
In `@src/components/clinical-dashboard/global-search-shell.tsx`:
- Around line 2-3: Update GlobalSearchShell’s ClinicalDashboard dependency to
use the existing lazy/dynamic import pattern instead of a static import,
preserving code-splitting so standalone shell routes do not load the dashboard
module. Keep the ClinicalDashboard rendering behavior unchanged when that branch
is selected.

In `@tests/ui-smoke.spec.ts`:
- Around line 56-69: Replace the undocumented React-props inspection in
waitForReactEventHandler with a stable readiness signal exposed by the relevant
component, such as a data-scroll-ready attribute set when its scroll handler is
mounted. Update the helper to poll that attribute through the Locator API,
preserving its timeout and success behavior, and ensure all existing call sites
continue using the helper unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 935d11c9-889a-4271-a1a6-a4f0b6a6049e

📥 Commits

Reviewing files that changed from the base of the PR and between f0eec3e and 1ca2f9f.

📒 Files selected for processing (48)
  • .env.example
  • .github/workflows/staging-tenancy.yml
  • docs/branch-review-ledger.md
  • docs/process-hardening.md
  • docs/staging-setup.md
  • docs/staging-tenancy-release-evidence.md
  • package.json
  • scripts/build-clinical-review-queue.ts
  • scripts/check-document-label-coverage.ts
  • scripts/classify-documents.ts
  • scripts/eval-quality.ts
  • scripts/production-readiness.ts
  • scripts/reconcile-registry-governance.ts
  • scripts/run-eval-safe.mjs
  • scripts/test-cross-tenant-staging.ts
  • scripts/verify-release-offline.mjs
  • src/app/page.tsx
  • src/components/ClinicalDashboard.tsx
  • src/components/DocumentViewer.tsx
  • src/components/clinical-dashboard/answer-result-surface.tsx
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/use-hide-on-scroll.ts
  • src/components/document-viewer/pdf-canvas-viewer.tsx
  • src/lib/answer-thread-storage.ts
  • src/lib/clinical-review-queue.ts
  • src/lib/health-response.ts
  • src/lib/rag-route-budget.ts
  • src/lib/rag.ts
  • src/lib/registry-corpus.ts
  • src/lib/types.ts
  • tests/answer-progress-ui-smoke.spec.ts
  • tests/answer-thread-storage.test.ts
  • tests/classify-documents.test.ts
  • tests/clinical-review-queue.test.ts
  • tests/cross-tenant-staging-config.test.ts
  • tests/document-label-coverage.test.ts
  • tests/eval-quality.test.ts
  • tests/health-route.test.ts
  • tests/offline-release-profile.test.ts
  • tests/playwright-scroll.ts
  • tests/production-readiness-offline.test.ts
  • tests/rag-answer-fallback.test.ts
  • tests/rag-route-budget.test.ts
  • tests/registry-corpus.test.ts
  • tests/registry-governance-reconciliation.test.ts
  • tests/retrieval-owner-filter-guard.test.ts
  • tests/ui-smoke.spec.ts
  • tests/ui-tools.spec.ts

Comment thread scripts/test-cross-tenant-staging.ts
Comment thread src/components/ClinicalDashboard.tsx Outdated
Comment thread src/components/DocumentViewer.tsx

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 98aaad43d2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/registry-corpus.ts
@BigSimmo

Copy link
Copy Markdown
Owner Author

@codex resolve actionable Codex review findings for this pull request and current head using the repository instructions. This is the pull request's single automatic repair pass: do not perform a fresh review, create new standalone findings, or request another review. Work only the existing unresolved Codex threads on the current head. Always fix P0 and P1 findings. For P2 and lower findings, fix only clear, scoped, low-risk issues; otherwise disposition them with a concise reason. After fixing or dispositioning a thread, reply in that thread with as the first line, followed by a concise summary; that marker authorizes the workflow to close that exact thread. If human input or new authorization is required, do not use the marker and leave the thread open with the blocker. Finish only after every actionable thread is fixed or dispositioned and closed, or explicitly left open for a human decision. Do not update the branch from main, address unrelated reviews, broaden scope, or create more than one scoped fix commit. Do not use external APIs, paid services, credentials, dependency changes, or broad refactors unless explicitly authorized. Add targeted tests where behavior changes and run the narrowest relevant validation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3b152ed1f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread package.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/DocumentViewer.tsx (1)

2613-2622: 🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

onPageChange breaks PdfCanvasViewer's memoization.

The inline arrow function passed as onPageChange gets a new identity on every DocumentViewer render, undermining the exact optimization documented a few lines above (handleSignedUrlExpired/handlePdfLoadSuccess are useCallback-wrapped specifically "so the memoised PdfCanvasViewer isn't re-rendered — and its page re-rastered — every time an unrelated parent state ... changes"). Now a source-search keystroke, composer focus toggle, or online/offline flip will re-render PdfCanvasViewer again.

🐛 Proposed fix
+  const handlePageChange = useCallback(
+    (page: number) => {
+      window.history.pushState(null, "", documentPageHref(documentId, page));
+    },
+    [documentId],
+  );
+
   ...
   <PdfCanvasViewer
     key={`${documentId}-${useNativePdfViewer ? "native" : "canvas"}`}
     url={signedUrl}
     title={documentDisplayTitle(document)}
     initialPage={initialPage}
     onUrlExpired={handleSignedUrlExpired}
     onLoadSuccess={handlePdfLoadSuccess}
-    onPageChange={(page) => {
-      window.history.pushState(null, "", documentPageHref(documentId, page));
-    }}
+    onPageChange={handlePageChange}
   />
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/DocumentViewer.tsx` around lines 2613 - 2622, Stabilize the
onPageChange prop passed to PdfCanvasViewer by defining the history-update
handler with useCallback in DocumentViewer, preserving the existing
documentPageHref behavior and dependencies. Replace the inline arrow function
with this memoized handler so unrelated DocumentViewer renders do not invalidate
PdfCanvasViewer memoization.
🧹 Nitpick comments (1)
src/components/DocumentViewer.tsx (1)

1629-1632: 📐 Maintainability & Code Quality | 🔵 Trivial

Minor: the conditional spread for scrollContainer is unnecessary.

useHideOnScroll's scrollContainer already defaults to null, so scrollContainer: shellScrollContainer (which is HTMLElement | null) is equivalent to the conditional-spread form. Simplifying removes an indirection with no behavior change.

♻️ Optional simplification
-  const scrollHidden = useHideOnScroll({
-    ...(shellScrollContainer ? { scrollContainer: shellScrollContainer } : {}),
-    resetKey: `${documentId}:${initialPage}:${chunkId ?? ""}`,
-  });
+  const scrollHidden = useHideOnScroll({
+    scrollContainer: shellScrollContainer,
+    resetKey: `${documentId}:${initialPage}:${chunkId ?? ""}`,
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/DocumentViewer.tsx` around lines 1629 - 1632, Update the
useHideOnScroll call to pass scrollContainer: shellScrollContainer directly,
removing the conditional spread while preserving the existing resetKey and
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/check-document-label-coverage.ts`:
- Around line 212-219: Centralize the registry-document predicate currently
implemented by isRegistryDocument in scripts/check-document-label-coverage.ts
and its counterpart in scripts/classify-documents.ts. Add one shared helper
accepting source_kind, source_path, file_name, and file_type, preserve the
existing registry-projection checks, and update both call
sites—scripts/check-document-label-coverage.ts:212-219 and
scripts/classify-documents.ts:161-168—to use it.

In `@scripts/eval-quality.ts`:
- Around line 287-293: Update configureEvalProviderEnvironment to make the
parsed providerMode authoritative: when it is "openai", explicitly set
process.env.RAG_PROVIDER_MODE to "openai" even if the environment currently
contains "offline", while preserving the existing offline credential cleanup.
Add a focused test covering openai selection with an ambient offline value, and
run the narrowest relevant test validation.

In `@scripts/test-cross-tenant-staging.ts`:
- Around line 587-605: Update the createClient calls for clientA, clientB, and
admin to use a bounded timeout-aware global.fetch through their client options.
Preserve the existing auth settings and apply the same transport configuration
to all three Supabase clients so sign-in, fixture writes, and cleanup cannot
hang indefinitely.

In `@src/components/ClinicalDashboard.tsx`:
- Around line 565-566: Update the answer-thread owner-switch flow in
ClinicalDashboard so persistence is gated by a committed owner that advances
only after the reset/restore microtask completes, rather than by
activeAnswerThreadOwnerIdRef.current during render. Explicitly clear the
previous owner during the switch, and ensure the persistence effect cannot write
the previous thread under the new owner until bootstrapping finishes.

In `@src/components/DocumentViewer.tsx`:
- Around line 2620-2622: Update the onPageChange handler in DocumentViewer to
avoid desynchronizing page state from browser history: use replaceState if
per-page Back/Forward entries are not intended, or implement popstate handling
that reads the URL page and restores initialPage/viewer state when navigating
history. Preserve the existing documentPageHref URL generation.

In `@src/lib/rag.ts`:
- Around line 3592-3593: Guard the unsupported-answer cache call near
setCachedAnswer with !routeDeadline.deadlineExceeded, and apply the same
condition to the generated-answer cache call in src/lib/rag.ts at lines
4494-4495. Add a targeted test covering an answer that exceeds its deadline
after generation and verifying it is not cached.
- Around line 3451-3455: Move deadline creation to the request-level flow before
the retrieval wait, specifically before searchChunksWithTelemetry and routing
execute, so the caller signal can abort stalled retrieval. Update the
routeDeadline setup around createAnswerRouteDeadline to derive the selected
route’s remaining budget from that earlier request deadline while preserving the
existing route.mode and startedAt inputs.
- Around line 3475-3476: Update the unsupported-route branch around route.mode
=== "unsupported" to catch deadline expiry from
routeDeadline.race(relatedDocumentsPromise), return the already-available
unsupported answer, and still dispose the related-document lookup resources. Add
the smallest targeted test covering a related-document lookup that outlives the
unsupported-route budget and verifies successful recovery plus disposal.

In `@src/lib/registry-corpus.ts`:
- Around line 243-317: The registry reconciliation flow must not overwrite
reviewer-managed generated-label metadata or confidence. Update
reconcileRegistryGeneratedLabels and its related reconciliation path to preserve
existing document_intent metadata and reviewer changes while updating only
generator-owned fields, using an existing-label metadata merge or a narrowly
scoped upsert.

---

Outside diff comments:
In `@src/components/DocumentViewer.tsx`:
- Around line 2613-2622: Stabilize the onPageChange prop passed to
PdfCanvasViewer by defining the history-update handler with useCallback in
DocumentViewer, preserving the existing documentPageHref behavior and
dependencies. Replace the inline arrow function with this memoized handler so
unrelated DocumentViewer renders do not invalidate PdfCanvasViewer memoization.

---

Nitpick comments:
In `@src/components/DocumentViewer.tsx`:
- Around line 1629-1632: Update the useHideOnScroll call to pass
scrollContainer: shellScrollContainer directly, removing the conditional spread
while preserving the existing resetKey and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 935d11c9-889a-4271-a1a6-a4f0b6a6049e

📥 Commits

Reviewing files that changed from the base of the PR and between 1dcc4d9 and 3c6cf9d.

📒 Files selected for processing (50)
  • .env.example
  • .github/workflows/staging-tenancy.yml
  • docs/branch-review-ledger.md
  • docs/process-hardening.md
  • docs/staging-setup.md
  • docs/staging-tenancy-release-evidence.md
  • package.json
  • scripts/build-clinical-review-queue.ts
  • scripts/check-document-label-coverage.ts
  • scripts/classify-documents.ts
  • scripts/eval-quality.ts
  • scripts/production-readiness.ts
  • scripts/reconcile-registry-governance.ts
  • scripts/run-eval-safe.mjs
  • scripts/test-cross-tenant-staging.ts
  • scripts/verify-release-offline.mjs
  • src/app/page.tsx
  • src/components/ClinicalDashboard.tsx
  • src/components/DocumentViewer.tsx
  • src/components/clinical-dashboard/answer-result-surface.tsx
  • src/components/clinical-dashboard/global-search-shell.tsx
  • src/components/clinical-dashboard/use-hide-on-scroll.ts
  • src/components/document-viewer/pdf-canvas-viewer.tsx
  • src/instrumentation.ts
  • src/lib/answer-thread-storage.ts
  • src/lib/clinical-review-queue.ts
  • src/lib/health-response.ts
  • src/lib/rag-route-budget.ts
  • src/lib/rag.ts
  • src/lib/registry-corpus.ts
  • src/lib/types.ts
  • tests/answer-progress-ui-smoke.spec.ts
  • tests/answer-thread-storage.test.ts
  • tests/classify-documents.test.ts
  • tests/clinical-review-queue.test.ts
  • tests/cross-tenant-staging-config.test.ts
  • tests/document-label-coverage.test.ts
  • tests/eval-quality.test.ts
  • tests/health-route.test.ts
  • tests/instrumentation.test.ts
  • tests/offline-release-profile.test.ts
  • tests/playwright-scroll.ts
  • tests/production-readiness-offline.test.ts
  • tests/rag-answer-fallback.test.ts
  • tests/rag-route-budget.test.ts
  • tests/registry-corpus.test.ts
  • tests/registry-governance-reconciliation.test.ts
  • tests/retrieval-owner-filter-guard.test.ts
  • tests/ui-smoke.spec.ts
  • tests/ui-tools.spec.ts

Comment thread scripts/check-document-label-coverage.ts Outdated
Comment thread scripts/eval-quality.ts
Comment thread scripts/test-cross-tenant-staging.ts
Comment thread src/components/ClinicalDashboard.tsx
Comment thread src/components/DocumentViewer.tsx
Comment thread src/lib/rag.ts
Comment thread src/lib/rag.ts
Comment thread src/lib/rag.ts Outdated
Comment thread src/lib/registry-corpus.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 978d4f462f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/reconcile-registry-governance.ts
Comment thread src/lib/answer-thread-storage.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1ece1b891e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/rag.ts
Comment thread src/lib/registry-corpus.ts
@BigSimmo
BigSimmo merged commit c0b76a5 into main Jul 14, 2026
72 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants